<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this</title>
</head>
<body>
<script>
    /*
    * 1.箭头函数的出现就是为了解决ES5中this指向混乱的问题
    * 2.箭头函数没有自己的this,它的this来自父级上下文,并且永远指向父级上下文
    * 3.箭头函数的this不会在调用的时候被改变, 因为箭头函数在声明的时候它的this就已经被永久的确定了
    * */


    {//ES5中this指向混乱
        let obj = {
            name: "obj",
            func() {
                console.log(this);//obj;

                let that = this;
                (function func1(){
                    console.log(that);//obj
                })()

                // (()=>{
                //     console.log(this);//obj
                // })()


                // let that = this;
                // // (()=>{
                // //     (js底层的代码)this = that;
                // //     console.log(this);//obj
                // // })()
                // function func1(){//闭包
                //     // this = that; //箭头函数内部处理逻辑
                //     console.log(that);//obj
                // }
                //
                // func1();
            }
        }
        obj.func();
    }
    {//箭头函数的形式
        let obj = {
            name: "obj",
            func() {
                console.log(this);//obj;

                let func1 =()=>{
                    console.log(this);//obj
                }
                func1();
            }
        }
        obj.func();
    }



    //改变this指向的情况
    //1.方法中 谁调用,this就指向谁,(.前面是谁,this就指向谁)
    //2.如果没有人调用的时候this默认的指向window
    //3.构造函数中的this, 指向通过这个构造函数创建出来的实例本身
    //4.强制改变this指向  call apply bind


    //全局 window
    //this === window
    a = 10;
    console.log(a);//10
    console.log(window.a);//10
    console.log(this.a);//10
    //this ===>EC 执行上下文

    {
        function fn(){
            console.log(this);//window
        }
        fn();

        let obj = {
            name: "obj",
            func: function(){
                console.log(this);//obj
            }
        };
        obj.func();
    }
    {
        let obj = {
            name: "obj",
            func(){
                console.log(this);//obj

                function fn(){
                    console.log(this);//window
                }
                fn();

                // setTimeout(function(){
                //     console.log(this);//window
                // },1000)
                // setTimeout(()=>{
                //     console.log("???",this);//
                // },1500)
            }
        };

        obj.func();
    }
    //js中this指向都有什么时候会不同
    {//1.方法中 谁调用,this就指向谁,(.前面是谁,this就指向谁)
        let obj = {
            name: "obj",
            func: function(){
                console.log(this);//obj
            }
        };
        obj.func();
    }
    {//2.如果没有人调用的时候this默认的指向window
        function fn(){
            console.log(this);//window
        }
        fn();
        // setTimeout(function(){
        //     console.log(this);//window
        // },1000)
    }
    {//3.构造函数中的this, 指向通过这个构造函数创建出来的实例本身
        //构造函数=> ES5中的类(普通函数和构造函数的区别:构造函数第一个字符大写) =>ES6 Class
        function Person(name){//
            this.name = name;
            this.age = 20;
            console.log("Person-->",this);
        }
        Person.prototype.sayHello = function (){
            console.log(this.name, "hello world")
        }
        let person = new Person("哈哈");
        person.sayHello();
    }
    {//4.强制改变this指向  call apply bind
        //call方法 语法  call(this的指向,function的参数)
        //apply方法 语法  apply(this的指向,[function的参数])
        //bind本身不回去执行要被改变this指向的这个方法,而是返回一个已经被改变了this指向的新方法
        let obj = {
            name: "haha",
            birthDay: 2000,
            year: 2021,
            age: function (p1, p2){
                console.log(this);//obj
                console.log("传递进去的参数",p1,p2);
                console.log(this.name + " 计算完成之后的年龄",this.year - this.birthDay);
            }
        }
        obj.age();
        //
        // obj.age.call({
        //     name: "呵呵",
        //     birthDay: 2001,
        //     year: 2051
        // },"--测试参数--","==测试==")
        //
        // obj.age.apply({
        //     name: "嘻嘻",
        //     birthDay: 1900,
        //     year: 2051
        // },["--测试参数01--","==测试参数02=="])
        let ageFunc = obj.age.bind({
            name: "bind",
            birthDay: 19,
            year: 20
        });
        console.log(ageFunc);
        ageFunc()

    }


</script>
</body>
</html>